package com.eoekun.dashboard.model.enums;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import com.alibaba.druid.util.StringUtils;
import com.eoekun.dashboard.util.CamelConvertUtil;

public class EnumGener {

    private final static String ENM_PATH = "src/main/resources/dev-data/sql/enum";
    private final static String REGEX = "`(?<name>[\\S+].*)`[\\S+\\s+].*'(?<desc>[\\S+\\s+].*)',";
    private final static String REGEX2 = "\\S+\\((\\S+)\\)";
    private final static String AUTHOR = System.getProperty("user.name");
    private final static String CREATE_TIME = getLocalTimeStr();
    // @formatter:off
    private final static String CODE_FORMAT = "package com.eoekun.dashboard.model.enums;\n" + 
            "\n" + 
            "import java.util.HashMap;\n" + 
            "import java.util.Map;\n" + 
            "import javax.validation.constraints.NotNull;\n" + 
            "\n" + 
            "/**\n" + 
            " * ${desc}\n" + 
            " * \n" + 
            " * @author ${author}\n" + 
            " * @createTime ${createTime}\n" + 
            " */\n" + 
            "public enum ${enumName} {\n" + 
            "    // @formatter:off\n" + 
            "    ${enums};\n" + 
            "    // @formatter:on\n" + 
            "    private ${valueType} value;\n" + 
            "    private String text;\n" + 
            "\n" + 
            "    private ${enumName}(${valueType} value, String text) {\n" + 
            "        this.value = value;\n" + 
            "        this.text = text;\n" + 
            "    }\n" + 
            "\n" + 
            "    /**\n" + 
            "     * \n" + 
            "     * @param value\n" + 
            "     * @return 若为空,则返回空字符串\n" + 
            "     * @author ${author}\n" + 
            "     * @createTime ${createTime}\n" + 
            "     */\n" + 
            "    public static String getText(${valueType} value) {\n" + 
            "        for (${enumName} enmm : ${enumName}.values()) {\n" + 
            "            if (enmm.getValue().equals(value)) {\n" + 
            "                return enmm.getText();\n" + 
            "            }\n" + 
            "        }\n" + 
            "        return \"\";\n" + 
            "    }\n" + 
            "\n" + 
            "    /**\n" + 
            "     * \n" + 
            "     * @param text\n" + 
            "     * @return ${valueType} 若不存在,则返回null\n" + 
            "     * @author ${author}\n" + 
            "     * @createTime ${createTime}\n" +  
            "     */\n" + 
            "    public static ${valueType} getValue(String text) {\n" + 
            "        for (${enumName} enmm : ${enumName}.values()) {\n" + 
            "            if (enmm.getText().equals(text)) {\n" + 
            "                return enmm.getValue();\n" + 
            "            }\n" + 
            "        }\n" + 
            "        return null;\n" + 
            "    }\n" + 
            "\n" + 
            "    public static ${enumName} getEnumByValue(${valueType} value) {\n" + 
            "        for (${enumName} enmm : ${enumName}.values()) {\n" + 
            "            if (enmm.getValue().equals(value)) {\n" + 
            "                return enmm;\n" + 
            "            }\n" + 
            "        }\n" + 
            "        return null;\n" + 
            "    }\n" + 
            "\n" + 
            "    public static ${enumName} getEnumByText(String text) {\n" + 
            "        for (${enumName} enmm : ${enumName}.values()) {\n" + 
            "            if (enmm.getText().equals(text)) {\n" + 
            "                return enmm;\n" + 
            "            }\n" + 
            "        }\n" + 
            "        return null;\n" + 
            "    }\n"+
            "\n" + 
            "    public static @NotNull Map<${valueType}, String> toMap() {\n" + 
            "        Map<${valueType}, String> map = new HashMap<>();\n" + 
            "        for (${enumName} enmm : ${enumName}.values()) {\n" + 
            "            map.put(enmm.value, enmm.text);\n" + 
            "        }\n" + 
            "        return map;\n" + 
            "    }\n"+
            "\n" + 
            "    public ${valueType} getValue() {\n" + 
            "        return value;\n" + 
            "    }\n" + 
            "\n" + 
            "    public String getText() {\n" + 
            "        return text;\n" + 
            "    }\n" + 
            "\n" + 
            "}\n" + 
            "";
    // @formatter:on


    public static void main(String[] args) throws IOException {
        List<String> lines = new ArrayList<>();
        lines.add("`task_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务状态(0.评审,1.排期,2.开发,3.提测,4.测试,5.回归,6.验收,7.发布,8.上线,9.延期,10.挂起)',");
        lines.add("`param_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '参数类型(1.参数类型,2.任务状态,3.任务类型,4.月度范围,5.友情链接,6.滚动tip,7.优先级,8.jira前缀,9.项目列表,10.开发成员,11.测试成员)',");

        Map<String, String> enumMap = convertMap(lines);
        String path = "src/main/java/com/wdai/dashboard/model/enums/";
        for (Entry<String, String> entry : enumMap.entrySet()) {
            String filePath = path + entry.getKey() + ".java";
            File file = new File(filePath);
            if (file.exists()) {
                System.err.println("enum exists:" + filePath);
                continue;
            }
            FileUtils.write(file, entry.getValue(), "utf-8");
        }
    }



    private static Map<String, String> convertMap(List<String> lines) {
        Pattern pattern = Pattern.compile(REGEX);
        Pattern pattern2 = Pattern.compile(REGEX2);
        Map<String, String> enumMap = new HashMap<>();
        for (String line : lines) {
            System.out.println("---------------------------------------------------------");
            Matcher m = pattern.matcher(line);
            String valueType = "Integer";
            if (m.find()) {
                String name = m.group("name");
                String desc = m.group("desc");
                String enumName = CamelConvertUtil.underlineToCamel(name + "Enum");
                Map<String, String> varMap = new HashMap<>();
                varMap.put("${author}", AUTHOR);
                varMap.put("${createTime}", CREATE_TIME);
                varMap.put("${desc}", desc);
                varMap.put("${enumName}", enumName);
                StringBuilder enumsSb = new StringBuilder();
                // 紧急性(0.低,1.中,2.高)
                Matcher m2 = pattern2.matcher(desc);
                if (m2.find()) {
                    String enums = m2.group(1);
                    String[] fields = enums.split(",");
                    for (String field : fields) {
                        String[] field2s = field.split("\\.");
                        String desc2 = field2s[0];
                        if (!StringUtils.isNumber(desc2)) {
                            desc2 = "\"" + desc2 + "\"";
                            valueType = "String";
                        }
                        enumsSb.append("/**\n" + "     * ").append(field)
                                .append("\n" + "     */\n    ").append(field2s[1]).append("(")
                                .append(desc2).append(", ").append("\"").append(field2s[1])
                                .append("\"),\n    ");
                    }
                }
                varMap.put("${enums}", enumsSb.toString());
                varMap.put("${valueType}", valueType);
                String content = repalceAll(CODE_FORMAT.toString(), varMap);
                System.out.println(content);
                enumMap.put(enumName, content);
            }

        }
        return enumMap;
    }


    private static String repalceAll(String codeFormat, Map<String, String> varMap) {
        String content = null;
        for (Entry<String, String> entry : varMap.entrySet()) {
            String replacement = entry.getValue();
            String regex =
                    entry.getKey().replace("$", "\\$").replace("{", "\\{").replace("}", "\\}");
            if (null == content) {
                content = codeFormat.replaceAll(regex, replacement);
            } else {
                content = content.replaceAll(regex, replacement);
            }
        }
        return content;
    }

    private static String getLocalTimeStr() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 ahh:mm:ss");
        return sdf.format(new Date());
    }

    @SuppressWarnings("unused")
    private static String[] read() throws IOException {
        File modelFile = new File(ENM_PATH);
        String proContent = FileUtils.readFileToString(modelFile, "utf-8");
        String[] lines = proContent.split("\n");
        return lines;
    }
}
